import { _decorator, Animation, Component, EventMouse, Input, input, Vec3 } from 'cc';
const { ccclass, property } = _decorator;

@ccclass('PlayerController')
export class PlayerController extends Component {

    private _jumpFlag: boolean = false;
    private _jumpDuration: number = 0.2;
    private _jumpingDeltaTime: number = 0;
    private _jumpSpeed: number = 0;
    private _curPosition: Vec3 = new Vec3();
    private _targetPosition: Vec3 = new Vec3();

    private _step: number = 0;

    @property(Animation)
    public bodyAni: Animation = null;

    onGameStart() {
        // 玩家开始游戏应该回到原始位置
        this.node.setPosition(0, 0, 0);
        this._step = 0;
        this.node.emit("jumpStepEvent", this._step);
        input.on(Input.EventType.MOUSE_DOWN, this.onMouseDown, this);
    }

    onGameEnd() {
        input.off(Input.EventType.MOUSE_DOWN, this.onMouseDown, this);
    }

    onMouseDown(event: EventMouse) {
        if (this._jumpFlag) {
            // 正在跳跃，不处理
            return;
        }
        // Handle keyboard input here
        const button = event.getButton();
        if (button === 0) {
            this.jumpByStep(1)
        } else if (button === 2) {
            this.jumpByStep(2)
        }
        
    }

    jumpByStep(step: number) {
        const jumpAnitationName = step == 1 ? "jumpOneStep" : "jumpTwoStep";
        const animState =  this.bodyAni.getState(jumpAnitationName);

        this._jumpFlag = true;
        this._jumpDuration = animState.length;
        this._jumpingDeltaTime = 0;
        this._jumpSpeed = step * 40 / this._jumpDuration;
        this._curPosition = this.node.getPosition();
        this._targetPosition.set(this._curPosition.x + step * 40, this._curPosition.y, this._curPosition.z);
     
        this.bodyAni.play(jumpAnitationName)

        this._step += step;
        this.node.emit("jumpStepEvent", this._step);
    }

    update(deltaTime: number) {
        if (this._jumpFlag) {
            if (this._jumpingDeltaTime < this._jumpDuration) {
                this._jumpingDeltaTime += deltaTime;
                const cur_position = this.node.getPosition();
                this.node.setPosition(cur_position.x + this._jumpSpeed * deltaTime, cur_position.y, 0);
            } else {
                this._jumpFlag = false;
                this.node.setPosition(this._targetPosition);
            }
        }
    }

    protected onDestroy(): void {
        input.off(Input.EventType.MOUSE_DOWN, this.onMouseDown, this);
    }
}

